/*
 *  Map.h
 *  Rempart
 *
 *
 */

#ifndef __MAP
#define __MAP

class Map;

#include <SFML/Graphics.hpp>
#include "Constants.h"


#include "OutOfMapException.h"
#include "CollisionException.h"
#include "EdgeException.h"

#include "Ground.h"
#include "Water.h"
#include "Wall.h"
#include "Canon.h"
#include "Ground.h"
#include "Tower.h"
#include "Boat.h"

#include "MouseOverPattern.h"

#include <fstream>
#include <iostream>
#include <math.h>

#include "Index.h"


class Map : public sf::Drawable{
	
public:
	
	static const int width = 960;
	static const int heigth = 643;
	static const int layers = 3;

	
	
		
	
	~Map();
	static Map* getInstance();
	
		
		
	bool isInMap(int x, int y);
	bool isInMap(const sf::Vector2<float>& position);
	
	bool isSecured(int x, int y, int z=0);
	
	void updateMapElement(int v,int x, int y);
	
	
	int getElementType(int x, int y,int z=0);
	virtual void setMouseOver(int x, int y);
	virtual void setMouseOver(MouseOverPattern* pattern,int x,int y);
	virtual void unsetMouseOver(int x, int y);
	virtual void unsetMouseOver();
	void dumpMapToFile();
	void loadFromFile();
	int getZoneIdOfElement(int x, int y);
	
	
	sf::Image getImage();
	sf::Sprite getSprite();
	void buildWall();
	void destroyWall(int x, int y);
	
	void buildCanon();
	void buildCanon(int x, int y);

	
	void buildBoat();
	void buildBoat(int x, int y);
	void destroyBoat(int x, int y);
	void destroyAllBoats();
	
	void triggerFire();
	void triggerBoatFire();
	
	const Wall* getRandomWall();
	int getSecuredTowerNumber();
	void manageWeapons();
	
	void updateZones();

private:

	bool isClosed;
	
	void buildWall(int x, int y);
	
	
	void checkZone(int x, int y);
	void propagation(int x, int y,Index<MapElement*>* encircledElements);
	void validateZone(int x, int y,Index<MapElement*>* encircledElements);

	Index<MapElement*>* mouseOverElements;
	Index<MapElement*>* securedList;
	Index<Canon*>* canonList;
	Index<Wall*>* wallList;
	Index<Tower*>* towerList;
	Index<Boat*>* boatList;
	Index<Water*>* waterList;


	
	MapElement* genRandomMap(int groundPercent=70);
	
	MapElement *mapElement[Map::layers][Map::width][Map::heigth];

	
	Map(); // cette classe est un Singleton
	static Map* instance;
	
	
	void Render(sf::RenderTarget& Target) const;
	
	
};

#endif